package com.wewins.fota.bean.dto;

import com.alibaba.fastjson.JSONObject;
import com.wewins.fota.common.constant.CommonConst;
import com.wewins.fota.common.constant.FotaCode;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.MapBindingResult;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
@Builder
public class CheckStatusReq {
    enum Param {
        PRODUCT,
        IMEI,
        VERSION,
        AUTO {
            @Override
            public String getDefaultValue() {
                return "-1";
            }
        },
        LANG,
        DEV {
            @Override
            public String getDefaultValue() {
                return "0";
            }
        };

        public String getName() {
            return this.name().toLowerCase();
        }

        public String getDefaultValue() {
            return "None_FOTA";
        }
    }

    @Getter
    @Setter
    private Map<String, String> params;


    public String getProduct() {
        return params.getOrDefault(Param.PRODUCT.getName(), Param.PRODUCT.getDefaultValue());
    }

    public void setProduct(String product) {
        this.params.put(Param.PRODUCT.getName(), product);
    }

    public String getImei() {
        return params.getOrDefault(Param.IMEI.getName(), Param.IMEI.getDefaultValue());
    }

    public void setImei(String imei) {
        this.params.put(Param.IMEI.getName(), imei);
    }

    public String getVersion() {
        return params.getOrDefault(Param.VERSION.getName(), Param.VERSION.getDefaultValue());
    }

    public void setVersion(String version) {
        this.params.put(Param.VERSION.getName(), version);
    }

    public int getAuto() {
        // 设备升级方式: 0:手动，1：自动 ==> 转成fota的升级方式：0：所有，1：手动，2：自动
        return Integer.parseInt(params.getOrDefault(Param.AUTO.getName(), Param.AUTO.getDefaultValue())) + 1;
    }

    public void setAuto(int auto) {
        this.params.put(Param.AUTO.getName(), String.valueOf(auto));
    }

    public String getLang() {
        return params.getOrDefault(Param.LANG.getName(), Param.LANG.getDefaultValue());
    }

    public void setLang(String lang) {
        this.params.put(Param.LANG.getName(), lang);
    }

    public boolean isDev() {
        // 1：表示开发模式，其他值均为生产模式
        return Integer.parseInt(params.getOrDefault(Param.DEV.getName(), Param.DEV.getDefaultValue())) == CommonConst.ENV_DEV;
    }

    public void setDev(int dev) {
        this.params.put(Param.DEV.getName(), String.valueOf(dev));
    }

    public Map<String, String> getOthers() {
        Map<String, String> map = new HashMap<>();
        List<String> fixParamNames = Stream.of(Param.values()).map(Param::getName).collect(Collectors.toList());
        for (String item : this.params.keySet()) {
            if (!fixParamNames.contains(item)) {
                map.put(item, this.params.get(item));
            }
        }
        return map;
    }

    public BindingResult check() {
        String name = this.getClass().getName();
        MapBindingResult result = new MapBindingResult(new HashMap<>(), name);
        StringBuilder builder = new StringBuilder("CMD:").append(FotaCode.CMD_VERSION_QUERY.getMessage());
        if (this.getProduct().equals(Param.PRODUCT.getDefaultValue())) {
            builder.append(", Param: ").append(Param.PRODUCT.getName()).append(" is invalid.");
            result.addError(new FieldError(name, Param.PRODUCT.getName(), "Is Invalid"));
        }

        if (this.getImei().equals(Param.IMEI.getDefaultValue())) {
            builder.append(", Param: ").append(Param.IMEI.getName()).append(" is invalid.");
            result.addError(new FieldError(name, Param.IMEI.getName(), "Is Invalid"));
        }

        if (this.getVersion().equals(Param.VERSION.getDefaultValue())) {
            builder.append(", Param: ").append(Param.VERSION.getName()).append(" is invalid.");
            result.addError(new FieldError(name, Param.VERSION.getName(), "Is Invalid"));
        }

        if (this.getAuto() != CommonConst.FOTA_UPDATE_TYPE_HANDLE && this.getAuto() != CommonConst.FOTA_UPDATE_TYPE_AUTO) {
            builder.append(", Param: ").append(Param.AUTO.getName()).append(" is invalid.");
            result.addError(new FieldError(name, Param.AUTO.getName(), "Is Invalid"));
        }

        if (result.getAllErrors().size() == 0) {
            return null;
        }
        builder.append(", Request param: ").append(this);
        log.error(builder.toString());
        return result;
    }

    @Override
    public String toString() {
        return JSONObject.toJSONString(this.params);
    }
}
